import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import matplotlib
import seaborn as sns
from datetime import datetime
import logging

font_path = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'

# 创建字体对象
my_font = fm.FontProperties(fname=font_path)

class ForexDataProcessor:
    """
    汇率数据处理器
    """
    
    def __init__(self):
        self.logger = logging.getLogger(__name__)
        # 设置中文字体
        plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'Noto Sans CJK']
        plt.rcParams['axes.unicode_minus'] = False
    
    def process_all_data(self, all_forex_data):
        """
        处理所有汇率数据
        """
        processed_data = {}
        
        for symbol, forex_info in all_forex_data.items():
            try:
                data = forex_info['data']
                name = forex_info['name']
                
                # 计算技术指标
                processed_df = self._calculate_indicators(data)
                
                processed_data[symbol] = {
                    'name': name,
                    'data': processed_df,
                    'summary': self._generate_summary(processed_df)
                }
                
            except Exception as e:
                self.logger.error(f"处理 {symbol} 数据时出错: {str(e)}")
                continue
        
        return processed_data
    
    def _calculate_indicators(self, df):
        """
        计算技术指标
        """
        try:
            df = df.copy()
            
            # 计算日收益率
            df['daily_return'] = df['close'].pct_change()
            
            # 计算移动平均线
            df['ma_5'] = df['close'].rolling(window=5).mean()
            df['ma_10'] = df['close'].rolling(window=10).mean()
            df['ma_20'] = df['close'].rolling(window=20).mean()
            
            # 计算波动率（20日滚动标准差）
            df['volatility'] = df['daily_return'].rolling(window=20).std()
            
            # 计算价格变化
            df['price_change'] = df['close'] - df['open']
            df['price_change_pct'] = (df['close'] - df['open']) / df['open'] * 100
            
            # 计算累计收益
            df['cumulative_return'] = (1 + df['daily_return']).cumprod() - 1
            
            return df
            
        except Exception as e:
            self.logger.error(f"计算技术指标时出错: {str(e)}")
            return df
    
    def _generate_summary(self, df):
        """
        生成数据摘要
        """
        try:
            latest_record = df.iloc[-1]
            first_record = df.iloc[0]
            
            summary = {
                'current_rate': latest_record['close'],
                'avg_rate': df['close'].mean(),
                'max_rate': df['close'].max(),
                'min_rate': df['close'].min(),
                'volatility': df['daily_return'].std(),
                'total_return': (latest_record['close'] - first_record['close']) / first_record['close'] * 100,
                'change_percent': (latest_record['close'] - first_record['close']) / first_record['close'] * 100,
                'data_points': len(df),
                'date_range': f"{df['date'].min().strftime('%Y-%m-%d')} 至 {df['date'].max().strftime('%Y-%m-%d')}"
            }
            
            return summary
            
        except Exception as e:
            self.logger.error(f"生成摘要时出错: {str(e)}")
            return {}
    
    def generate_statistics(self, processed_data):
        """
        生成统计信息
        """
        statistics = {}
        
        for symbol, data_info in processed_data.items():
            try:
                summary = data_info['summary']
                statistics[symbol] = summary
                
            except Exception as e:
                self.logger.error(f"生成 {symbol} 统计信息时出错: {str(e)}")
                continue
        
        return statistics
    
    def save_to_files(self, processed_data, output_dir):
        """
        保存数据到文件
        """
        try:
            import os
            os.makedirs(output_dir, exist_ok=True)
            
            # 保存每个货币对的详细数据
            for symbol, data_info in processed_data.items():
                df = data_info['data']
                filename = f"{output_dir}/{symbol}_forex_data.csv"
                df.to_csv(filename, index=False, encoding='utf-8')
                self.logger.info(f"已保存 {symbol} 数据到 {filename}")
            
            # 保存汇总数据
            summary_data = []
            for symbol, data_info in processed_data.items():
                summary = data_info['summary'].copy()
                summary['symbol'] = symbol
                summary['name'] = data_info['name']
                summary_data.append(summary)
            
            summary_df = pd.DataFrame(summary_data)
            summary_filename = f"{output_dir}/forex_summary.csv"
            summary_df.to_csv(summary_filename, index=False, encoding='utf-8')
            self.logger.info(f"已保存汇总数据到 {summary_filename}")
            
        except Exception as e:
            self.logger.error(f"保存文件时出错: {str(e)}")
    
    def create_visualizations(self, processed_data, output_dir):
        """
        创建可视化图表
        """
        try:
            import os
            os.makedirs(output_dir, exist_ok=True)
            
            # 为每个货币对创建走势图
            for symbol, data_info in processed_data.items():
                df = data_info['data']
                name = data_info['name']
                
                # 创建子图
                fig, axes = plt.subplots(2, 2, figsize=(15, 10))
                fig.suptitle(f'{name} ({symbol}) Exchange rate analysis',  fontsize=16)
                
                # 1. 价格走势图
                axes[0, 0].plot(df['date'], df['close'], label='Closing price', linewidth=2)
                axes[0, 0].plot(df['date'], df['ma_5'], label='5-day moving average', alpha=0.7)
                axes[0, 0].plot(df['date'], df['ma_10'], label='10-day moving average', alpha=0.7)
                axes[0, 0].set_title('Price trend')
                axes[0, 0].legend()
                axes[0, 0].grid(True, alpha=0.3)
                
                # 2. 日收益率
                axes[0, 1].plot(df['date'], df['daily_return'], color='green', alpha=0.7)
                axes[0, 1].set_title('Daily return')
                axes[0, 1].grid(True, alpha=0.3)
                axes[0, 1].axhline(y=0, color='red', linestyle='--', alpha=0.5)
                
                # 3. 成交量
                axes[1, 0].bar(df['date'], df['volume'], alpha=0.7, color='orange')
                axes[1, 0].set_title('Trading volume')
                axes[1, 0].grid(True, alpha=0.3)
                
                # 4. 波动率
                axes[1, 1].plot(df['date'], df['volatility'], color='red', alpha=0.7)
                axes[1, 1].set_title('Volatility')
                axes[1, 1].grid(True, alpha=0.3)
                
                # 调整布局
                plt.tight_layout()
                
                # 保存图表
                chart_filename = f"{output_dir}/{symbol}_chart.png"
                plt.savefig(chart_filename, dpi=300, bbox_inches='tight')
                plt.close()
                
                self.logger.info(f"已保存 {symbol} 图表到 {chart_filename}")
            
            # 创建汇总对比图
            self._create_comparison_chart(processed_data, output_dir)
            
        except Exception as e:
            self.logger.error(f"创建可视化图表时出错: {str(e)}")
    
    def _create_comparison_chart(self, processed_data, output_dir):
        """
        创建汇率对比图
        """
        try:
            fig, axes = plt.subplots(2, 2, figsize=(16, 12))
            fig.suptitle('Exchange rate comparative analysis', fontsize=16)
            
            # 准备数据
            symbols = list(processed_data.keys())
            names = [processed_data[s]['name'] for s in symbols]
            current_rates = [processed_data[s]['summary']['current_rate'] for s in symbols]
            volatilities = [processed_data[s]['summary']['volatility'] for s in symbols]
            changes = [processed_data[s]['summary']['change_percent'] for s in symbols]
            
            # 1. 当前汇率对比
            axes[0, 0].bar(range(len(symbols)), current_rates, color='skyblue')
            axes[0, 0].set_title('Current exchange rate comparison')
            axes[0, 0].set_xticks(range(len(symbols)))
            axes[0, 0].set_xticklabels(symbols, rotation=45)
            axes[0, 0].grid(True, alpha=0.3)
            
            # 2. 波动率对比
            axes[0, 1].bar(range(len(symbols)), volatilities, color='orange')
            axes[0, 1].set_title('Volatility comparison')
            axes[0, 1].set_xticks(range(len(symbols)))
            axes[0, 1].set_xticklabels(symbols, rotation=45)
            axes[0, 1].grid(True, alpha=0.3)
            
            # 3. 涨跌幅对比
            colors = ['red' if x < 0 else 'green' for x in changes]
            axes[1, 0].bar(range(len(symbols)), changes, color=colors)
            axes[1, 0].set_title('Price change comparison (%)')
            axes[1, 0].set_xticks(range(len(symbols)))
            axes[1, 0].set_xticklabels(symbols, rotation=45)
            axes[1, 0].grid(True, alpha=0.3)
            axes[1, 0].axhline(y=0, color='black', linestyle='-', alpha=0.5)
            
            # 4. 汇率走势对比（标准化）
            for symbol in symbols:
                df = processed_data[symbol]['data']
                # 标准化处理
                normalized_close = (df['close'] - df['close'].min()) / (df['close'].max() - df['close'].min())
                axes[1, 1].plot(df['date'], normalized_close, label=symbol, alpha=0.8)
            
            axes[1, 1].set_title('Comparison of exchange rate trends (normalized)')
            axes[1, 1].legend()
            axes[1, 1].grid(True, alpha=0.3)
            
            plt.tight_layout()
            
            # 保存对比图
            comparison_filename = f"{output_dir}/forex_comparison.png"
            plt.savefig(comparison_filename, dpi=300, bbox_inches='tight')
            plt.close()
            
            self.logger.info(f"已保存对比图表到 {comparison_filename}")
            
        except Exception as e:
            self.logger.error(f"创建对比图表时出错: {str(e)}")
